﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Linq;
using System.Windows.Threading;

namespace iControl.Windows
{
    /// <summary>
    /// Interaction logic for QuickSelectWindow.xaml
    /// </summary>
    public partial class QuickSelectWindow : Window
    {
        #region Variable Declration
        private ObservableCollection<PlaylistItem> _PlaylistItems;
        private System.Windows.Media.Animation.Storyboard _HideAnimationStoryBoard;
        private System.Windows.Media.Animation.Storyboard _ShowAnimationStoryBoard;
        private string _PrvSearchString = "{E3A3A1ED-7EA0-44b9-95B6-D832CAC749AE}";
        #endregion

        #region Delegate Declaration
        private delegate void AddTrackToPlaylistDelegate(IEnumerator<PlaylistItem> tracks);
        #endregion

        #region Constructor
        public QuickSelectWindow()
        {
            this.InitializeComponent();
            this.Hide();

            _HideAnimationStoryBoard = this.FindResource("HideAnimation") as System.Windows.Media.Animation.Storyboard;
            _HideAnimationStoryBoard.Completed += new EventHandler(HideAnimation_Completed);

            _ShowAnimationStoryBoard = this.FindResource("ShowAnimation") as System.Windows.Media.Animation.Storyboard;

            _PlaylistItems = new ObservableCollection<PlaylistItem>();
            lstPlaylist.ItemsSource = _PlaylistItems;

#if DEBUG
            this.Topmost = false;
#endif
        }


        #endregion

        #region Event Handlers
        private void Window_KeyDown(object sender, KeyEventArgs e)
        {
            if( e.Key == Key.Escape )
                this.Close();
        }
        private void Window_Activated(object sender, EventArgs e)
        {
            Controller.DefaultInstance.KeyboardHook.KeyDown += new System.Windows.Forms.KeyEventHandler(KeyboardHook_KeyDown);
        }
        private void Window_Deactivated(object sender, EventArgs e)
        {
            Controller.DefaultInstance.KeyboardHook.KeyDown -= new System.Windows.Forms.KeyEventHandler(KeyboardHook_KeyDown);
        }

        private void DragWindow(object sender, MouseButtonEventArgs e)
        {
            DragMove();
        }
        private void btnCloseX_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void btnClearSearchBox_Click(object sender, RoutedEventArgs e)
        {
            txtFilter.Text = string.Empty;
        }

        private void txtFilter_TextChanged(object sender, TextChangedEventArgs e)
        {
            lstPlaylist.SelectedIndex = -1;
            lstPlaylist.Items.Filter = new Predicate<object>(obj => ((PlaylistItem)obj).TrackName.ToUpper().Contains(txtFilter.Text.ToUpper()));
        }
        private void btnSearchLibrary_Click(object sender, RoutedEventArgs e)
        {
            LoadPlaylist();
        }

        private void PlaylistItem_DoubleClick(object sender, MouseButtonEventArgs e)
        {
            PlaySelectedTrack();
        }

        private void KeyboardHook_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            if( !this.Dispatcher.CheckAccess() )
            {
                this.Dispatcher.Invoke(new System.Windows.Forms.KeyEventHandler(this.KeyboardHook_KeyDown), sender, e);
                return;
            }

            if( e.KeyCode == System.Windows.Forms.Keys.Enter )
            {
                if( lstPlaylist.SelectedIndex == -1 )
                {
                    if( lstPlaylist.Items.Count == 1 )
                        lstPlaylist.SelectedIndex = 0;
                    else
                        return;
                }

                PlaySelectedTrack();
                this.Close();
            }
            else if( e.KeyCode == System.Windows.Forms.Keys.Down )
            {
                if( lstPlaylist.SelectedIndex + 1 < lstPlaylist.Items.Count )
                {
                    lstPlaylist.SelectedIndex++;
                    lstPlaylist.ScrollIntoView(lstPlaylist.SelectedItem);
                }
            }
            else if( e.KeyCode == System.Windows.Forms.Keys.Up )
            {
                if( lstPlaylist.SelectedIndex - 1 >= 0 )
                {
                    lstPlaylist.SelectedIndex--;
                    lstPlaylist.ScrollIntoView(lstPlaylist.SelectedItem);
                }
            }
        }

        private void HideAnimation_Completed(object sender, EventArgs e)
        {
            base.Hide();
            this.WindowState = WindowState.Minimized;
        }
        #endregion

        #region Methods
        private void LoadPlaylist()
        {
            if( txtFilter.Text == _PrvSearchString )
                return;            

            btnSearchLibrary.IsEnabled = false;
            pbLoading.Visibility = Visibility.Visible;
            pbLoading.Animate();

            IEnumerable<PlaylistItem> tracks = null;
            _PlaylistItems.Clear();
            lstPlaylist.SelectedIndex = -1;
            lstPlaylist.Items.Filter = null;

            if( string.IsNullOrEmpty(txtFilter.Text) )
            {
                if( Controller.DefaultInstance.CurrentTrack != null )
                {
                    var artistsName = Controller.DefaultInstance.CurrentTrack.Artist;
                    tracks = Controller.DefaultInstance.GetTracks(artistsName, iTunesLib.ITPlaylistSearchField.ITPlaylistSearchFieldArtists);
                }
                else
                {
                    Controller.DefaultInstance.ShowITunes();
                }
            }
            else
            {
                var filter = txtFilter.Text;                
                tracks = Controller.DefaultInstance.GetTracks(filter, iTunesLib.ITPlaylistSearchField.ITPlaylistSearchFieldVisible);
            }

            if( tracks != null )
            {
                this.Dispatcher.BeginInvoke(DispatcherPriority.Background,
                    new AddTrackToPlaylistDelegate(AddTrackToPlaylist), tracks.GetEnumerator());
            }
        }        

        private void AddTrackToPlaylist(IEnumerator<PlaylistItem> enumerator)
        {
            var track = enumerator.Current;

            if( track != null )
                _PlaylistItems.Add(track);

            if( enumerator != null && enumerator.MoveNext() )
            {
                this.Dispatcher.BeginInvoke(DispatcherPriority.Background,
                        new AddTrackToPlaylistDelegate(AddTrackToPlaylist), enumerator);
            }
            else
            {
                pbLoading.StopAnimation();
                pbLoading.Visibility = Visibility.Hidden;
                btnSearchLibrary.IsEnabled = true;
                txtFilter.Focus();
            }
        }


        private void PlaySelectedTrack()
        {
            if( lstPlaylist.SelectedIndex == -1 )
                return;

            var track = lstPlaylist.SelectedItem as PlaylistItem;
            Controller.DefaultInstance.Play(track);
        }

        public new void Show()
        {
            if( this.Visibility != Visibility.Visible )
            {
                if( !string.IsNullOrEmpty(txtFilter.Text) || Controller.DefaultInstance.CurrentTrack != null )
                {
                    txtFilter.Focus();
                    txtFilter.SelectAll();

                    this.WindowState = WindowState.Normal;
                    this.Opacity = 0;
                    base.Show();

                    _ShowAnimationStoryBoard.Begin(this);
                }
            }

            LoadPlaylist();
        }
        public new void Close()
        {
            _PrvSearchString = txtFilter.Text;
            _HideAnimationStoryBoard.Begin(this);
        }
        #endregion


    }
}